/**
  ******************************************************************************
  * @file    IAP/src/download.c
  * @author  MCD Application Team
  * @version V3.3.0
  * @date    10/15/2010
  * @brief   This file provides the software which allows to download an image
  *          to internal Flash.
  ******************************************************************************
  * @copy
  *
  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  *
  * <h2><center>&copy; COPYRIGHT 2010 STMicroelectronics</center></h2>
  */

/** @addtogroup IAP
  * @{
  */
/* Includes ------------------------------------------------------------------*/
#include "common.h"

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
extern uint8_t file_name[FILE_NAME_LENGTH];
uint8_t tab_1024[1024] =
{
    0
};

uint8_t otaBuff[2048] = {0};
FATFS fs;
FIL file;
FILINFO FileInfo;

/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/


/**
  * @brief  Download a file via serial port
  * @param  None
  * @retval None
  */
void SerialDownload(void)
{
    uint8_t Number[10] = "          ";
    int32_t Size = 0;

    printf("Waiting for the file to be sent ... (press 'a' to abort)\n\r");
    Size = Ymodem_Receive(&tab_1024[0]);

    if (Size > 0)
    {
        printf("\n\n\r Programming Completed Successfully!\n\r--------------------------------\r\n Name:%s", file_name);
        Int2Str(Number, Size);
        printf("\n\r Size: %d Bytes\r\n", Size);
        printf("--------------------------------\\n");
		setUpgradeFlag(SUCCESS_UPGRADE);
		printf("\n\r 0x080F6800 = %04x\n",REPROGRAM_FLAG);
    }
    else if (Size == -1)
    {
        printf("\n\n\rThe image size is higher than the allowed space memory!\n\r");
		NVIC_SystemReset();
    }
    else if (Size == -2)
    {
        printf("\n\n\rVerification failed!\n\r");
		NVIC_SystemReset();
    }
    else if (Size == -3)
    {
        printf("\r\n\nAborted by user.\n\r");
		NVIC_SystemReset();
    }
    else
    {
        printf("\n\rFailed to receive the file!\n\r");
		printf("\n\r 0x080F6800 = %04x\n",REPROGRAM_FLAG);
		delay(2000);
		NVIC_SystemReset();
    }
}

int OtaDownload(void)
{
	int i,j, cnt = 0;
	uint32_t pageCnt = 0; 
	uint32_t fileSize = 0;
	uint8_t *pBuff = NULL;
	FLASH_Status FLASHStatus = FLASH_COMPLETE;
	FRESULT res = FR_OK;
	UINT br = 1;
	uint32_t FlashDest =  ApplicationAddress;
	
	printf("\r\nwaiting ota data write to flash\r\n");
	res = f_mount(&fs,"0:",1);
	if(res != FR_OK){
		printf("f_mount spi flash fail, retring ...\r\n");
		res = f_mount(&fs,"0:",1);
		if(res != FR_OK){
			printf("f_mount spi flash fail\r\n");
			return -1;
		}
	}
	res = f_stat("/ota.bin", &FileInfo);
	if(res == FR_OK){
		fileSize = FileInfo.fsize;
		printf("file info:\r fileSize:%d \t fileName:%s\r\n",fileSize, FileInfo.fname);	
		
		printf("Erase page ing ...\r\n");
		pageCnt = FLASH_PagesMask(FileInfo.fsize);
		for (i = 0; (i < pageCnt) && (FLASHStatus == FLASH_COMPLETE); i++){			
			FLASHStatus = FLASH_ErasePage(FlashDest + (PAGE_SIZE * i));
		}
		if(FLASHStatus == FLASH_COMPLETE && i == pageCnt)
			printf("Erase all page finish\r\n");
		else{
			printf("Erase page error\r\n");
			return -1;
		}
		
		res = f_open(&file, "/ota.bin", FA_READ);
		if(res != FR_OK){
			printf("open ota.bin file fail\r\n");
			f_close(&file);
			return -1;
		}
		FLASH_Unlock();
		while(1){
			res = f_read(&file, otaBuff, sizeof(otaBuff), &br);
			if(br == 0)	break;	
			if(res == FR_OK){
				cnt += br;
				printf("loading (%d/%d)\r\n",cnt/1024,fileSize/1024);
//				pBuff = (uint32_t)otaBuff;
				pBuff = otaBuff;
				for (j = 0; (j < br) ; j += 4){
					FLASH_ProgramWord(FlashDest, *(uint32_t *)pBuff);
					if (*(uint32_t *)FlashDest != *(uint32_t *)pBuff){
						printf("Program word error\r\n");
						f_close(&file);
						return -1;
					}
					FlashDest += 4;
					pBuff += 4;
				}
				printf("FlashDest: %x\r\n",FlashDest);
			}
			else{
				printf("read ota.bin file fail\r\n");
				f_close(&file);
				return -1;
			}
		}
		FLASH_Lock();
		
	}
	else{
		printf("ota.bin file no exist\r\n");
		return -1;
	}
	f_close(&file);
	delay(2400000);
	return 0;	

}

int bakDownload(void)
{
	int i,j,cnt = 0;
	uint32_t pageCnt = 0; 
	uint32_t fileSize = 0;
	uint8_t * pBuff = NULL;
	FLASH_Status FLASHStatus = FLASH_COMPLETE;
	FRESULT res = FR_OK;
	UINT br = 1;
	uint32_t FlashDest =  ApplicationAddress;
	
	printf("\r\nwaiting bak data write to flash\r\n");
	res = f_mount(&fs,"0:",1);
	if(res != FR_OK){
		printf("f_mount spi flash fail, retring ...\r\n");
		res = f_mount(&fs,"0:",1);
		if(res != FR_OK){
			printf("f_mount spi flash fail\r\n");
			return -1;
		}
	}
	res = f_stat("/bak.bin", &FileInfo);
	if(res == FR_OK){
		fileSize = FileInfo.fsize;
		printf("file info:\r fileSize:%d \t fileName:%s\r\n",fileSize, FileInfo.fname);	
		
		printf("Erase page ing ...\r\n");
		pageCnt = FLASH_PagesMask(FileInfo.fsize);
		for (i = 0; (i < pageCnt) && (FLASHStatus == FLASH_COMPLETE); i++){			
			FLASHStatus = FLASH_ErasePage(FlashDest + (PAGE_SIZE * i));
		}
		if(FLASHStatus == FLASH_COMPLETE && i == pageCnt)
			printf("Erase all page finish\r\n");
		else{
			printf("Erase page error\r\n");
			return -1;
		}
		
		res = f_open(&file, "/bak.bin", FA_READ);
		if(res != FR_OK){
			printf("open bak.bin file fail\r\n");
			f_close(&file);
			return -1;
		}
		FLASH_Unlock();
		while(1){
			res = f_read(&file, otaBuff, sizeof(otaBuff), &br);
			if(br == 0)	break;	
			if(res == FR_OK){
				cnt += br;
				printf("loading (%d/%d)\r\n",cnt/1024,fileSize/1024);
//				pBuff = (uint32_t)otaBuff;
				pBuff = otaBuff;
				for (j = 0; (j < br) ; j += 4){
					FLASH_ProgramWord(FlashDest, *(uint32_t *)pBuff);
					if (*(uint32_t *)FlashDest != *(uint32_t *)pBuff){
						printf("Program word error\r\n");
						f_close(&file);
						return -1;
					}
					FlashDest += 4;
					pBuff += 4;
					
				}
				printf("FlashDest: %x\tj: %d\r\n",FlashDest,j);
			}
			else{
				printf("read bak.bin file fail\r\n");
				f_close(&file);
				return -1;
			}
		}
		FLASH_Lock();
		
	}
	else{
		printf("bak.bin file no exist\r\n");
		return -1;
	}
	f_close(&file);
	delay(2400000);
	return 0;	
}



/**
  * @}
  */

/*******************(C)COPYRIGHT 2010 STMicroelectronics *****END OF FILE******/
